{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Introduction"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The PyData ecosystem has a number of core Python data containers that allow users to work with a wide array of datatypes, including:\n",
    "\n",
    "* [Pandas](https://pandas.pydata.org): DataFrame, Series (columnar/tabular data)\n",
    "* [Rapids cuDF](https://docs.rapids.ai/api/cudf/stable/): GPU DataFrame, Series (columnar/tabular data)\n",
    "* [DuckDB](https://www.duckdb.org/): DuckDB is a fast in-process analytical database\n",
    "* [Polars](https://www.pola.rs/): Polars is a fast DataFrame library/in-memory query engine (columnar/tabular data)\n",
    "* [Dask](https://www.dask.org): DataFrame, Series (distributed/out of core arrays and columnar data)\n",
    "* [XArray](https://xarray.pydata.org): Dataset, DataArray (labelled multidimensional arrays)\n",
    "* [Streamz](https://streamz.readthedocs.io): DataFrame(s), Series(s) (streaming columnar data)\n",
    "* [Intake](https://github.com/ContinuumIO/intake): DataSource (data catalogues)\n",
    "* [GeoPandas](https://geopandas.org): GeoDataFrame (geometry data)\n",
    "* [NetworkX](https://networkx.github.io/documentation/stable/): Graph (network graphs)\n",
    "\n",
    "Many of these libraries have the concept of a high-level plotting API that lets a user generate common plot types very easily. The native plotting APIs are generally built on [Matplotlib](https://matplotlib.org), which provides a solid foundation, but means that users miss out the benefits of modern, interactive plotting libraries for the web like [Bokeh](https://docs.bokeh.org) and [HoloViews](https://holoviews.org).\n",
    "\n",
    "**hvPlot** provides a high-level plotting API built on HoloViews that provides a general and consistent API for plotting data in all the formats mentioned above.\n",
    "\n",
    "As a first simple illustration of using hvPlot, let's create a small set of random data in Pandas to explore:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "\n",
    "index = pd.date_range('1/1/2000', periods=1000)\n",
    "df = pd.DataFrame(np.random.randn(1000, 4), index=index, columns=list('ABCD')).cumsum()\n",
    "\n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Pandas default .plot()\n",
    "\n",
    "Pandas provides Matplotlib-based plotting by default, using the  `.plot()` method:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "df.plot();"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The result is a PNG image that displays easily, but is otherwise static. \n",
    "\n",
    "## Switching Pandas backend\n",
    "\n",
    "To allow using hvPlot directly with Pandas we have to import `hvplot.pandas` and swap the Pandas backend with:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import hvplot.pandas  # noqa\n",
    "\n",
    "pd.options.plotting.backend = 'holoviews'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df.plot()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## .hvplot()\n",
    "\n",
    "If we instead change `%matplotlib inline` to `import hvplot.pandas` and use the ``df.hvplot`` method, it will now display an interactively explorable [Bokeh](https://bokeh.pydata.org) plot with panning, zooming, hovering, and clickable/selectable legends:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "df.hvplot()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This interactive plot makes it much easier to explore the properties of the data, without having to write code to select ranges, columns, or data values manually. Note that while pandas, dask and xarray all use the `.hvplot` method, `intake` uses hvPlot as its main plotting API, which means that is available using `.plot()`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## hvPlot native API\n",
    "\n",
    "For the plot above, hvPlot dynamically added the Pandas `.hvplot()` method, so that you can use the same syntax as with the Pandas default plotting.  If you prefer to be more explicit, you can instead work directly with hvPlot objects:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from hvplot import hvPlot\n",
    "hvplot.extension('bokeh')\n",
    "\n",
    "plot = hvPlot(df)\n",
    "plot(y=['A', 'B', 'C', 'D'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Switching the plotting extension to Matplotlib or Plotly\n",
    "\n",
    "While the default plotting extension of hvPlot is [Bokeh](https://bokeh.pydata.org), it is possible to load either Matplotlib or Plotly with `.extension()` and later switch from a plotting library to another with `.output()`. More information about working with multiple plotting backends can be found in the [plotting extensions guide](Plotting_Extensions.ipynb)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "hvplot.extension('matplotlib')\n",
    "\n",
    "df.hvplot(rot=30)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Getting help\n",
    "\n",
    "When working inside IPython or the Jupyter notebook hvplot methods will automatically complete valid keywords, e.g. pressing tab after declaring the plot type will provide all valid keywords and the docstring:\n",
    "\n",
    "```python\n",
    "df.hvplot.line(<TAB>\n",
    "```\n",
    "\n",
    "Outside an interactive environment ``hvplot.help`` will bring up information providing the ``kind`` of plot, e.g.:\n",
    "\n",
    "```python\n",
    "hvplot.help('line')\n",
    "```\n",
    "\n",
    "For more detail on the available options see [this page](../ref/plotting_options/index.md)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Working with Ruff\n",
    "\n",
    "In most cases, `import hvplot.pandas` is imported and never used directly. This will make linters like Ruff flag it as an [`unused-import`](https://docs.astral.sh/ruff/rules/unused-import/). This can either be ignored with a `# noqa: F401` or global being set in the `pyproject.toml` with [`allowed-unused-imports`](https://docs.astral.sh/ruff/settings/#lint_pyflakes_allowed-unused-imports).\n",
    "\n",
    "```toml\n",
    "[tool.ruff.lint.pyflakes]\n",
    "allowed-unused-imports = [\"hvplot.pandas\"]\n",
    "```\n",
    "\n",
    "This configuration requires Ruff version 0.6.9 or greater to be installed."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "## Next steps\n",
    "\n",
    "Now that you can see how hvPlot is used, let's jump straight in and discover some of the more powerful things we can do with it in the [Plotting](Plotting.ipynb) section."
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
